package com.flbill.service.impl;

import com.flbill.common.utils.BaseContext;
import com.flbill.common.utils.JwtUtils;
import com.flbill.mapper.SignInMapper;
import com.flbill.mapper.UserMapper;
import com.flbill.pojo.dto.LoginDTO;
import com.flbill.pojo.dto.RegisterDTO;
import com.flbill.pojo.entity.SignIn;
import com.flbill.pojo.entity.User;
import com.flbill.pojo.vo.LoginVO;
import com.flbill.service.UserService;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.beans.beancontext.BeanContext;
import java.time.LocalDate;
import java.time.LocalDateTime;

@Service
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    private final SignInMapper signInMapper;

    public UserServiceImpl(UserMapper userMapper, PasswordEncoder passwordEncoder, SignInMapper signInMapper) {
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
        this.signInMapper = signInMapper;
    }

    @Override
    public LoginVO login(LoginDTO loginDTO) {
        // 1. 根据用户名查询用户
        User user = userMapper.findByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 2. 校验密码
        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 3. 校验用户状态
        if (user.getStatus() != 1) {
            throw new RuntimeException("账号已被禁用");
        }

        // 4. 生成token
        String token = JwtUtils.generateToken(user.getId(), user.getUsername());

        // 5. 构建返回对象
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(token);

        LoginVO.UserInfoVO userInfoVO = new LoginVO.UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        loginVO.setUserInfo(userInfoVO);

        return loginVO;
    }

    @Override
    public void register(RegisterDTO registerDTO) {
        // 1. 检查用户名是否已存在
        User existingUser = userMapper.findByUsername(registerDTO.getUsername());
        if (existingUser != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 2. 创建新用户
        User user = new User();
        BeanUtils.copyProperties(registerDTO, user);

        // 3. 加密密码
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));

        // 4. 设置其他属性
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        user.setStatus(1);

        // 5. 保存用户
        userMapper.insert(user);
    }

    @Override
    public User getUser() {
        //获取id
        Integer id = BaseContext.getCurrentId();
        //通过id查询用户
        return userMapper.selectById(id);
    }

    @Override
    public void signIn() {
        Integer  id = BaseContext.getCurrentId();
        SignIn signIn = new SignIn();
        signIn.setUserId(id);
        signIn.setSignDate(LocalDate.now());
        //查询今日是否已经签到
        SignIn signIn1 = signInMapper.qurryBySignDate(signIn);
        if (signIn1 != null) {
            throw new RuntimeException("今日已签到");
        }
        signIn.setCreateTime(LocalDateTime.now());
        signInMapper.signIn(signIn);

    }

    @Override
    public Integer countSignIn() {
        //获取这个月的起点和终点
        LocalDate  start = LocalDate.now().withDayOfMonth(1);
        LocalDate  end = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth());
        return signInMapper.countSignIn(start, end);
    }

    @Override
    public Boolean checkSignIn() {
        //获取id
        Integer  id = BaseContext.getCurrentId();
        //获取今日时间
        LocalDate today = LocalDate.now();
        SignIn  signIn = new SignIn();
        signIn.setUserId(id);
        signIn.setSignDate(today);
        //查询今日是否已经签到
        SignIn newsignIn = signInMapper.qurryBySignDate(signIn);
        return newsignIn != null;
    }

    @Override
    public Float getExpectedExpense() {
        Integer id = BaseContext.getCurrentId();
        return userMapper.PlanExpensePie(id);
    }
} 